home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HAM Radio 3.2
/
Ham Radio Version 3.2 (Chestnut CD-ROMs)(1993).ISO
/
rtty
/
tlmdc
/
tlmdc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-01-30
|
18KB
|
810 lines
#include <stdio.h>
#include <dos.h>
#include <ctype.h>
#include <time.h>
#include <malloc.h>
#include <string.h>
#include <conio.h>
#include <process.h>
#include <graph.h>
/* kiss tnc routines for various - HEP/RWM */
int getbyte(),port,instat();
#define FEND 0300 /* Frame End */
#define FESC 0333 /* Frame Escape */
#define TFEND 0334 /* Transposed frame end */
#define TFESC 0335 /* Transposed frame escape */
#define SSIDMD 0x60
#define SSIDMS 0x61
unsigned char pkt[300],echo=0;
unsigned long time_out,now;
unsigned char line[336],dump=0;
unsigned char *in_buf;
FILE *dumpr,*dumpa;
union REGS inreg,outreg;
struct tm *gmt;
unsigned char satellite=4,com_str[]="COM1:9600,N,8,1",*satname[]={"PACSAT",
"DOVE","WEBER","LUSAT"},newsat=0,rawdmp[40],ascdmp[40];
struct eqn {
unsigned char channel,name[16],units[9],ok,value;
float a0,a1,a2;
} tlmval[80];
void asc_enab(),asc_disab();
main(argc,argv)
int argc;
char *argv[];
{
int ch,frame_l,i;
long timeit,addr;
unsigned char *buf,*bufc;
void tlm(),status(),check_call();
i=1;
while (argv[i] != NULL) {
*argv[i] = toupper(*argv[i]);
switch(*argv[i]) {
case 'C':{
strcpy(com_str,argv[i]);
break;
}
default : break;
}
i++;
}
/* Set up serial port */
setcom(com_str);
_clearscreen(_GCLEARSCREEN);
main_men();
while(1) {
if (kbhit() != 0) {
ch = getch();
ch = toupper(ch);
switch(ch) {
case 'F':{
if(dump) {
dump = 0;
fcloseall();
}
_settextwindow(1,1,25,80);
_clearscreen(_GCLEARSCREEN);
_outtext("Input raw data file to read: ");
scanf("%s",rawdmp);
if ((dumpr = fopen(rawdmp,"rb")) == NULL) {
_outtext("\nFile Not found. Strike a key");
getch();
main_men();
break;
}
_clearscreen(_GCLEARSCREEN);
_settextposition(1,70);
if (satellite != 4) _outtext(satname[satellite]);
else _outtext(" ");
_settextposition(25,55);
_outtext("Q=Quit,space to continue");
frame_l = 0;
while (frame_l != -1) {
frame_l=dsk_frame(pkt,dumpr);
if (frame_l < 0 ) {
fclose(dumpr);
_settextposition(25,55);
while(kbhit() != 0) getch();
_outtext("File end, strike a key ");
getch();
break;
}
ax25r(pkt,frame_l);
if (strstr(line,">TLM") != NULL) {
check_call();
tlm();
} else if ((buf=strstr(line,"uptime")) != NULL) {
_settextposition(1,1);
_outtext(buf);
}
else if (strstr(line,">STATUS") != NULL) {
check_call();
status();
frame_l = getch();
if (toupper(frame_l) == 'Q') break;
}
if(newsat) {
_settextposition(1,70);
_outtext(" ");
_settextposition(1,70);
_outtext(satname[satellite]);
newsat = 0;
}
}
_clearscreen(_GCLEARSCREEN);
main_men();
break;
}
case 'D': {
if (dump == 0) {
_settextwindow(1,1,25,80);
_clearscreen(_GCLEARSCREEN);
_outtext("Input raw data dump file: ");
scanf("%s",rawdmp);
_outtext("\nInput ascii dump file: ");
scanf("%s",ascdmp);
if (((dumpr = fopen(rawdmp,"ab")) == NULL) ||
((dumpa = fopen(ascdmp,"at")) == NULL)) {
perror("Error opening files");
dump = 0;
} else dump = 1;
main_men();
} else {
dump = 0;
fcloseall();
}
break;
}
case 'Q': {
_clearscreen(_GCLEARSCREEN);
asc_disab(port);
fcloseall();
exit(0);
}
case 'U':{
_clearscreen(_GCLEARSCREEN);
system("command");
main_men();
break;
}
case 'T': {
_settextwindow(1,1,25,80);
_clearscreen(_GCLEARSCREEN);
_settextposition(1,70);
if (satellite != 4) _outtext(satname[satellite]);
else _outtext(" ");
_settextposition(25,60);
_outtext("Keystroke to Quit");
do {
if (instat(port)){
frame_l=rec_frame(pkt);
if (frame_l != -1) {
ax25r(pkt,frame_l);
if (dump) {
fputs(line,dumpa);
}
if (strstr(line,">TLM") != NULL) {
check_call();
tlm();
} else if (strstr(line,">STATUS") != NULL) {
check_call();
status();
} else if ((in_buf=strstr(line,"uptime")) != NULL) {
_settextposition(1,1);
_outtext(in_buf);
}
}}
if(newsat) {
_settextposition(1,70);
_outtext(" ");
_settextposition(1,70);
_outtext(satname[satellite]);
newsat = 0;
}
} while (kbhit() == 0);
if (getch() == 0) getch();
_clearscreen(_GCLEARSCREEN);
main_men();
break;
}
}
}
_settextwindow(1,1,24,80);
do {
if(newsat) {
_settextwindow(25,1,25,80);
_settextposition(1,1);
_outtext(" ");
_settextposition(1,1);
_outtext(satname[satellite]);
_settextwindow(1,1,24,80);
newsat = 0;
}
if (instat(port) != 0) {
_settextposition(24,1);
frame_l=rec_frame(pkt);
if (frame_l != -1) {
ax25r(pkt,frame_l);
check_call();
_outtext(line);
if (dump) fputs(line,dumpa);
}
}
} while (kbhit() == 0);
}
}
/* Decode the raw KISS frames which have been stored on DISK*/
int dsk_frame(ubuf,dat_file)
unsigned char *ubuf;
FILE *dat_file;
{
int c,frame_size;
unsigned char *buf;
while((c=fgetc(dat_file)) != FEND)
if (c == EOF)
if (feof(dat_file)) return -1;
kludge_garb:
buf=ubuf;
while( (c = fgetc(dat_file)) == FEND)
if (c == EOF)
if (feof(dat_file)) return -1;
c = fgetc(dat_file); /* ignore KISS type code */
if (c == EOF)
if(feof(dat_file)) return -1;
frame_size = 0;
do{
if(c == FESC){
c = fgetc(dat_file);
switch(c){
case TFEND:
*buf++ = FEND;
frame_size++;
break;
case TFESC:
*buf++ = FESC;
frame_size++;
break;
default:
break;
}
}
else{
if (c == EOF)
if(feof(dat_file)) return -1;
*buf++ = c;
frame_size++;
}
c = fgetc(dat_file);
} while( c != FEND);
/* If we get a short frame becuase the main loop doesn't read
except after it sends a command, go and restart this frame,
i.e., assume that the "end" is the start of a new frame. */
if (frame_size<14) goto kludge_garb;
return frame_size;
}
/* Telemetry format routine */
static unsigned char *t;
void tlm()
{
int a,b;
unsigned char *print_tlm();
if ((t=strchr(in_buf,':')) != NULL){
t=in_buf;
}
else return;
while (sscanf(t," %x:%x",&a,&b)==2) {
_settextposition(3+(a/3),(a%3)*26+1);
printf("%-25.25s ",print_tlm(a,b));
t= t+6;
}
}
/* Decode the telemetry from the tlm table values */
static unsigned char printit[40];
unsigned char *print_tlm(chan,value)
unsigned char chan,value;
{
float fvalue;
struct eqn *ptr;
ptr = &tlmval[chan];
if (ptr->ok == 1) {
ptr->value = value;
fvalue = value;
fvalue = fvalue * (fvalue * ptr->a2 + ptr->a1) + ptr->a0;
sprintf(printit,"%-14.14s %7.3f %c ",ptr->name,fvalue,ptr->units[0]);
} else *printit=0;
return printit;
}
/* Menu routine */
main_men()
{
_settextwindow(25,1,25,80);
_clearscreen(_GCLEARSCREEN);
if (satellite != 4) {
_settextposition(25,1);
_outtext(satname[satellite]);
}
_settextposition(1,10);
_outtext("D = Toggle Dump, T = Tlm Decode, F = Decode File, Q = Quit");
_settextwindow(1,1,24,80);
}
/* Decode the status line from the telemetry */
void status()
{
int tx,txp,bcr,sb;
_settextposition(25,1);
switch (satellite) {
case 0: {
sscanf(&in_buf[9]," %2X",&bcr);
sscanf(&in_buf[18]," %2X",&txp);
sscanf(&in_buf[21]," %2X",&tx);
sscanf(&in_buf[27]," %2X",&sb);
sprintf(line,"TXA:%1u TXB:%1u TX Pwr:%1X SbT:%1X BCR:%2X",
1^(tx&1),1^((tx&2)>>1),txp&0xF,(sb>>7)^1,bcr);
_outtext(line);
break;
}
case 1 :{
sscanf(&in_buf[9]," %2X",&bcr);
sscanf(&in_buf[18]," %2X",&txp);
sscanf(&in_buf[21]," %2X",&tx);
sscanf(&in_buf[27]," %2X",&sb);
sprintf(line,"TXA:%1u TXB:%1u TX Pwr:%1X SbT:%1X BCR:%2X",
(tx&1),((tx&2)>>1),txp&0xF,(sb>>7)^1,bcr);
_outtext(line);
break;
}
case 2: {
sscanf(&in_buf[9]," %2X",&bcr);
sscanf(&in_buf[18]," %2X",&txp);
sscanf(&in_buf[21]," %2X",&tx);
sprintf(line,"TXA:%1u TXB:%1u TX Pwr:%1X, BCR:%2X",
1^(tx&1),1^((tx&2)>>1),txp&0xF,bcr);
_outtext(line);
break;
}
case 3: {
sscanf(&in_buf[9]," %2X",&bcr);
sscanf(&in_buf[18]," %2X",&txp);
sscanf(&in_buf[21]," %2X",&tx);
sprintf(line,"TXA:%1u TXB:%1u TX Pwr:%1X, BCR:%2X",
1^(tx&1),1^((tx&2)>>1),txp&0xF,bcr);
_outtext(line);
break;
}
}
}
/* Make sure we are decoding with the correct equations, if not, then
read in the appropriate file */
void check_call()
{
FILE *tlm_dat;
unsigned char tmpsat,tlmline[81];
struct eqn *ptr;
for(tmpsat=0;tmpsat<4;tmpsat++) {
if(strstr(line,satname[tmpsat]) != NULL) {
if (tmpsat != satellite) {
satellite = tmpsat;
newsat = 1;
if((tlm_dat=fopen(satname[tmpsat],"rt")) == NULL) {
puts("OOPS, you forgot to leave those files around!");
fcloseall();
exit(0);
}
tmpsat = 0;
memset(tlmval,0,80*sizeof(tlmval[0]));
while (fgets(tlmline,80,tlm_dat) != NULL) {
ptr = &tlmval[tmpsat++];
sscanf(tlmline," %X",&ptr->channel);
strncpy(ptr->name,&tlmline[6],15);
*(strchr(ptr->name,':')) = 0;
ptr->name[15]=0;
sscanf(&tlmline[21]," %f",&ptr->a0);
sscanf(&tlmline[34]," %f",&ptr->a1);
sscanf(&tlmline[46]," %f",&ptr->a2);
sscanf(&tlmline[59],"%7s",ptr->units);
ptr->units[8]=0;
ptr->ok=1;
}
fclose(tlm_dat);
}
return;
}
}
}
/* Horrible AX.25 handler, receive only */
ax25r(frame,framel)
unsigned char *frame;
int framel;
{
unsigned char *buf,*bufc,lineptr=0;
int i,j,k,endadr=0;
buf = bufc = frame;
buf[framel]=0;
/* Find the end of the address field */
do {
/* Fix up addresses and SSID's into readable form */
/* Pick off the ssid from the shit in byte 7 of each address */
k = bufc[6]&1;
bufc[6] = ((bufc[6] >> 1) & 0x0F);
if (bufc[6] < 10) bufc[6] += '0';
else bufc[6] += 'A'-10;
/* Shift the bits where they belong in each character of the
address */
for(i=0;i<6;i++) {
bufc[i] >>= 1;
}
bufc += 7;
endadr++;
} while ( k == 0);
/* Output header line */
/* For each callsign field */
/* Output a dash, SSID, and arrow pointing to direction, screw
the heard/digipeated bit */
bufc = &buf[7];
for(j=0;j<6;j++) line[lineptr++] = bufc[j];
line[lineptr++] ='-';
line[lineptr++] = buf[13];
line[lineptr++] ='>';
for(j=0;j<6;j++) line[lineptr++] = buf[j];
line[lineptr++] ='-';
line[lineptr++] = buf[6];
line[lineptr++]=' ';
/* line[lineptr++]='V';
line[lineptr++]=' ';*/
/* Output the call and SSID of repeaters */
/* for(i=endadr-1,bufc=buf+(endadr-1)*7;i>=2;i--,bufc -= 7) {
for(j=0;j<6;j++) line[lineptr++] =bufc[j];
line[lineptr++] = '-';
line[lineptr++] = bufc[6];
line[lineptr++] = ' ';
}
line[lineptr++] = ' ';*/
/* Is it a U frame, I frame, or S frame ? */
buf = frame + 7*endadr;
switch((*buf) & 0x1) {
case 0 : { /* It is an I frame */
while ((bufc=strchr(&buf[2],'\r')) != NULL) *bufc = '\n';
sprintf(&line[lineptr],"NR=%1u P/F=%1u NS=%1u PID=%2X\n%s",
(unsigned) (((*buf)&0xE0)>>5),
(unsigned) (((*buf)&0x10)>>4),
(unsigned)(((*buf)&0xF)>>1),
(unsigned) buf[1],&buf[2]);
bufc = &line[strlen(line)-1];
if (*bufc != '\n') {
*(bufc+1) = '\n';
*(bufc+2) = 0;
}
break;
}
case 1: {
switch( (*buf) & 0x2) {
case 0: {
switch ((*buf) & 0xC) {
case 0: {
sprintf(&line[lineptr],"RR NR=%1u P/F=%1u\n",(unsigned) (((*buf) & 0xE0)>>5),
(unsigned) ((*buf) & 0x10)>>4);
break;
}
case 4: {
sprintf(&line[lineptr],"RNR NR=%1u P/F=%1u\n",(unsigned) (((*buf) & 0xE0)>>5),
(unsigned) ((*buf) & 0x10)>>4);
break;
}
case 8: {
sprintf(&line[lineptr],"REJ NR=%1u P/F=%1u\n",(unsigned) (((*buf) & 0xE0)>>5),
(unsigned) ((*buf) & 0x10)>>4);
break;
}
}
break;
}
case 2:{
switch(((*buf) & 0xE0)>>5) {
case 0 :{
if ((*buf & 0x0C) != 0) sprintf(&line[lineptr]," DM\n");
else {
while ((bufc=strchr(&buf[2],'\r')) != NULL) *bufc = '\n';
in_buf = &buf[2];
time(&now);
gmt = gmtime(&now);
sprintf(&line[lineptr],"%s%s",asctime(gmt),in_buf);
bufc = &line[strlen(line)-1];
if (*bufc != '\n') {
*(bufc+1) = '\n';
*(bufc+2) = 0;
}
}
break;
}
case 1: {
sprintf(&line[lineptr]," SABM\n");
break;
}
case 2: {
sprintf(&line[lineptr]," DISC\n");
break;
}
case 3: {
sprintf(&line[lineptr]," UA\n");
break;
}
case 4: {
sprintf(&line[lineptr]," FRMR");
break;
}
}
break;
}
}
break;
}
}
}
int rec_frame(ubuf)
unsigned char *ubuf;
{
unsigned char c;
int frame_size;
unsigned char *buf;
time(&time_out);
time_out+=3;
while(getbyte() != FEND) {
time(&now);
if (now>time_out) return -1;
}
kludge_garb:
buf=ubuf;
/* wait for start of frame */
while( (c = getbyte()) == FEND) {
time(&now);
if (now>time_out) return -1;
}
/* ignore any extra FENDS */
c = getbyte(); /* ignore KISS type code */
frame_size = 0;
do{
time(&now);
if (now>time_out) return -1;
if(c == FESC){
c = getbyte();
switch(c){
case TFEND:
*buf++ = FEND;
frame_size++;
break;
case TFESC:
*buf++ = FESC;
frame_size++;
break;
default:
break;
}
}
else{
*buf++ = c;
frame_size++;
}
c = getbyte();
} while( c != FEND);
/* If we get a short frame because the main loop doesn't read
except after it sends a command, go and restart this frame,
i.e., assume that the "end" is the start of a new frame. */
if (frame_size<14) goto kludge_garb;
return frame_size;
}
/* Following serial io routines are taken from Quiktrak */
static unsigned char b1[8] = { '1', '1', '3', '6', '1', '2', '4', '9' };
static unsigned char b2[8] = { '1', '5', '0', '0', '2', '4', '8', '6' };
static unsigned char pars[4] = { 'N', 'O', 'N', 'E' };
static unsigned char stops[2] = { '1', '2' };
static unsigned char wlens[4] = { '?', '?', '7', '8' };
/*setcom, sets up the COM port*/
setcom(setstr)
unsigned char *setstr;
{
unsigned char *p;
int baud, par, stop, wlen;
short ok;
union REGS inreg, outreg;
/*
* Command line to upper case.
*/
for (p = setstr; *p; p++) if (islower(*p)) *p = toupper(*p);
/*
* Find port number.
*/
for (p = setstr; *p && (*p != ':'); p++);
if (*p != ':') {
error("No colon after COMn");
return;
}
port = (int) (*(p - 1) - '0') - 1;
if ((port < 0) || (port > 7)) {
error("Port number out of range");
return;
}
p++;
if (!*p) {
error("Parameters missing");
return;
}
/*
* Find baud rate.
*/
ok = 0;
for (baud = 0; !ok && (baud < 8); baud++)
{
ok = (*p == b1[baud]) && (*(p + 1) == b2[baud]);
}
baud--;
if (!ok) {
error("Baud rate not correct");
return;
}
for (; *p && (*p != ','); p++);
if (!*p++) {
error("Missing parameter");
return;
}
if (!*p) {
error("Missing parameter");
return;
}
/*
* Find parity.
*/
ok = 0;
for (par = 0; !ok && (par < 4); par++)
{
ok = (pars[par] == *p);
}
par--;
if (!ok) {
error("Parity not N, E, or O");
return;
}
for (; *p && (*p != ','); p++);
if (!*p++) {
error("Missing parameter");
return;
}
if (!*p) {
error("Missing parameter");
return;
}
/*
* Find word length.
*/
ok = 0;
for (wlen = 0; !ok && (wlen < 4); wlen++)
{
ok = (wlens[wlen] == *p);
}
wlen--;
if (!ok) {
error("Word length is not 7 or 8");
return;
}
for (; *p && (*p != ','); p++);
if (!*p++) {
error("Missing parameter");
return;
}
if (!*p) {
error("Missing parameter");
return;
}
/*
* Find number of stop bits.
*/
ok = 0;
for (stop = 0; !ok && (stop < 2); stop++)
{
ok = (stops[stop] == *p);
}
stop--;
if (!ok) {
error("Number of stop bits not 1 or 2");
return;
}
/* Compute control byte */
inreg.h.al = 32 * baud + 8 * par + 4 * stop + wlen;
printf(" COM%d:%c%c,%c,%c,%c = %x\n", port + 1,
b1[baud], b2[baud], pars[par], wlens[wlen], stops[stop], inreg.h.al);
inreg.x.dx = port;
inreg.h.ah = 0;
int86 (0x14, &inreg, &outreg); /* Set the speed,etc using the BIOS */
asc_enab(port); /* Turn on interrupt handler */
}
int getbyte()
{
int x;
do{
time(&now);
if (now>time_out) return -1;
else{
x = rcvbyte(port);
}
} while(x == -1);
x &= 0xff;
if (dump) fputc(x,dumpr);
return x;
}
error(str)
char *str;
{
perror(str);
exit(0);
}